import { _decorator, Button, find, instantiate, Label, Node, ProgressBar, ScrollView, UITransform, Vec3 } from 'cc';
import GlobalDC from '../../../../frame/common/data.global.center';
import { ScrollList } from '../../../../frame/component/scroll.list';
import { BaseUI } from '../../../../frame/component/ui.base';
import GameDC from '../../../data/data.game.center';
import ConfManager from '../../../manager/config.manager';
import DataManager from '../../../manager/data.manager';
import { Popup } from '../pop-up';
const { ccclass, property } = _decorator;

@ccclass('UIAchieveMaster')
export class UIAchieveMaster extends BaseUI {
	private scroll: ScrollView;
	private scroll_list: ScrollList;
	private ui_scroll: UITransform;
	private float_view: UITransform;
	private base_view: UITransform;
	private ui_lock: UITransform;
	private total_bar: ProgressBar;
	private curr_bar: ProgressBar;
	private lbl_progress_curr: Label;
	private lbl_next_level: Label;

	private demo_lbl_free: Node;
	private demo_lbl_master: Node;
	private demo_lbl_level: Node;

	private va_lock: mtec.cc.VecAssist;

	protected initAfterOnLoad(){
		this.init();
	}

	protected start(){
		this.adaptUI();
		this.initUIStatus();
		this.scroll.scrollToTop(0.1);
	}

	protected onEnable(){
		DataManager.ConfigInited.then(()=>this.refreshUI());
	}

	protected _click_event_: { [name: string]: (this: UIAchieveMaster, button: Button) => void; } = {
		'active-master'(btn){
			btn.interactable = false;
			this.activeMaster(btn);
		}
	}

	protected listening(){
		let lbl_time = this.node.getChildByName('lbl-time').getComponent(Label);
		let Day10 = mtec.time.ONE_DAY * 10;
		let [d, h, m, s] = [0, 0, 0, 0];

		let residue = 0;
		let list = [
			this.follow(GameDC.User, 'master_free_level', (o, v)=>this.refreshUI(), false),
			this.follow(GameDC.User, 'master_level', (o, v)=>this.refreshUI(), false),
			this.follow(GlobalDC.Status, 'curr_time', (o, now)=>{
				residue = Day10 - now + GameDC.User.master_time;
				s = residue / 1000;
				m = s / 60;
				h = m / 60;
				d = h / 24;
				lbl_time.string = Math.floor(d)+'D ' + [h%24, m%60, s%60].map(v=>Math.floor(v).toString().padStart(2, '0')).join(':');
			}),
			this.follow(GameDC.User, 'master', ()=>this.refreshUI(), false)
		];
		return list;
	}

	private init(){
		this.scroll = this.node.getChildByName('scroll-view').getComponent(ScrollView);
		this.ui_scroll = this.scroll.getComponent(UITransform);
		this.ui_lock = this.scroll.node.getChildByName('block-shade').getComponent(UITransform);
		this.va_lock = new mtec.cc.VecAssist(this.ui_lock.node);
		this.base_view = this.scroll.content.parent.getChildByName('base').getComponent(UITransform);
		this.float_view = this.scroll.content.parent.getChildByName('float').getComponent(UITransform);
		this.scroll_list = this.scroll.getComponent(ScrollList);
		this.scroll_list.onRefreshContent(this.onRefreshContent, this);
		this.scroll_list.onScrollCall(this.onScroll, this);
		this.scroll_list.onInitItem(this.initItem, this);
		this.scroll_list.onRenderItem(this.renderItem, this);
		this.total_bar = this.base_view.node.getChildByName('bar').getComponent(ProgressBar);
		let temp_node = find('info/level', this.node);
		this.curr_bar = temp_node.getChildByName('bar').getComponent(ProgressBar);
		this.lbl_progress_curr = temp_node.getChildByName('lbl-bar').getComponent(Label);
		this.lbl_next_level = temp_node.getChildByName('lbl-level').getComponent(Label);

		this.demo_lbl_free = this.float_view.node.getChildByName('lbl-free');
		this.demo_lbl_master = this.float_view.node.getChildByName('lbl-master');
		this.demo_lbl_level = this.float_view.node.getChildByName('lbl-level');

		[this.demo_lbl_free, this.demo_lbl_master, this.demo_lbl_level].forEach(n=>n.active = false);
	}

	private adaptUI(){
		let ui_parent = this.node.parent.getComponent(UITransform);
		this.node.getComponent(UITransform).setContentSize(ui_parent.width / 3, ui_parent.height);

		let view_width = ui_parent.width * 1008 / 1080 / 3;
		let view_height = ui_parent.height - 243;
		this.scroll.node.getComponent(UITransform).setContentSize(view_width, view_height);
		this.scroll.node.getChildByName('background').getComponent(UITransform).setContentSize(view_width, view_height);
		this.scroll.node.getChildByName('fake-collar').getComponent(UITransform).width = view_width;
		this.scroll.content.parent.parent.getComponent(UITransform).setContentSize(view_width-30, view_height-15);
		this.scroll.content.parent.getComponent(UITransform).setContentSize(view_width-30, view_height-165);
	}

	private initUIStatus(){
		this.node.setPosition(mtec.cc.VecAssist.getPosition(this.node, 'left', 'center'));

		this.scroll.node.setPosition(mtec.cc.VecAssist.getPosition(this.scroll.node, 'center', 'bottom'));
		this.scroll.content.parent.parent.setPosition(mtec.cc.VecAssist.getPosition(this.scroll.content.parent.parent, 'center', 'bottom'));
		let va_view = new mtec.cc.VecAssist(this.scroll.content.parent);
		va_view.getPosition('center', 'bottom');
		va_view.vec.add3f(0, 100, 0);
		this.scroll.content.parent.setPosition(va_view.vec);

		let time_node = this.scroll.node.getChildByName('time');
		let va_time = new mtec.cc.VecAssist(time_node);
		va_time.getPosition('center', 'top');
		va_time.vec.add3f(0, -5, 0);

		time_node.setPosition(va_time.vec);

		let fake_coller = this.scroll.node.getChildByName('fake-collar');
		fake_coller.setPosition(mtec.cc.VecAssist.getPosition(fake_coller, 'center', 'top'));

		(<const>[
			['lbl-active', 'ACTIVATE NOW!'],
			['lbl-free', 'Free'],
			['lbl-master', 'Master Pass']
		]).forEach(([name, text])=>this.node.getChildByName(name).getComponent(Label).string = text);

		DataManager.UserInfoSynced.then(()=>{
			let master = GameDC.User.master;
			this.node.getChildByName('active-master').active = !master;
			this.node.getChildByName('lbl-active').active = !master;
		})
	}

	private lock_vec = {
		bind: new Vec3(),
		temp: new Vec3(),
		out: new Vec3()
	}

	private refreshUI(){
		let data_list = ConfManager.masterList;

		let next_idx = 0;
		while(data_list[next_idx].level <= GameDC.User.master_free_level && next_idx < data_list.length-1){
			next_idx++;
		}
		let next_data = data_list[next_idx];

		let remove_count = next_data.eliminateCount + Math.min(0, DataManager.master_remove-next_data.remove_total);

		this.curr_bar.progress = remove_count / next_data.eliminateCount;
		this.lbl_progress_curr.string = remove_count + ' / ' + next_data.eliminateCount;
		this.lbl_next_level.string = next_data.level.toString();

		this.total_bar.progress = Math.min(1, (next_idx+this.curr_bar.progress)/data_list.length);

		this.scroll_list.getItemPositionByIndex(next_idx, this.lock_vec.bind);
		this.lock_vec.bind.add3f(0, -120, 0);

		this.refreshLockUI();
		this.renderList();
	}

	private renderList(){
		this.scroll_list.setDataList(ConfManager.masterList, 'level');
	}

	private renderItem(view: ScrollView, node: Node, data: typeof ConfManager.masterList[number], cache_map: Map<Node, ItemCache>){

		let cache = cache_map.get(node);
		if(!cache){
			cache = this.createItemCache(node);
			cache_map.set(node, cache);
		}

		cache.lbl_free.string = 'x'+data.commonDiamondCount;
		cache.lbl_master.string = 'x'+data.specialPassport.count;
		cache.lbl_level.string = data.level.toString();

		[cache.vec_lbl_free, cache.vec_lbl_master, cache.vec_lbl_level].forEach(vec=>vec.set(node.position));
		cache.vec_lbl_free.add3f(-270, -39, 0);
		cache.vec_lbl_master.add3f(273.5, -39, 0);
		cache.vec_lbl_level.add3f(0, -110, 0);

		cache.lbl_free.node.setPosition(cache.vec_lbl_free);
		cache.lbl_master.node.setPosition(cache.vec_lbl_master);
		cache.lbl_level.node.setPosition(cache.vec_lbl_level);

		cache.icon_free_check.active = data.level <= GameDC.User.master_free_level;
		cache.icon_master_lock.active = !GameDC.User.master;
		cache.icon_master_check.active = data.level <= GameDC.User.master_level;

		['icon-diamond', 'icon-prop-stash', 'icon-prop-revoke', 'icon-prop-shuffle'].forEach((name, idx)=>{
			cache.master_node.getChildByName(name).active = data.specialPassport.type == (idx+1);
		});
	}

	private initItem(view: ScrollView, node: Node, cache_map: Map<Node, ItemCache>){
		let cache = this.createItemCache(node);
		cache_map.set(node, cache);
		cache.vec_lbl_free.add3f(-270, -39, 0);
		cache.vec_lbl_master.add3f(273.5, -39, 0);
		cache.vec_lbl_level.add3f(0, -110, 0);

		cache.lbl_free.node.setPosition(cache.vec_lbl_free);
		cache.lbl_master.node.setPosition(cache.vec_lbl_master);
		cache.lbl_level.node.setPosition(cache.vec_lbl_level);
	}

	private onScroll(view: ScrollView, ui_content: UITransform){
		this.base_view.node.setPosition(ui_content.node.position);
		this.float_view.node.setPosition(ui_content.node.position);
		this.refreshLockUI();
	}

	private onRefreshContent(view: ScrollView, ui_content: UITransform){
		[this.base_view, this.float_view].forEach(ui=>{
			ui.setContentSize(ui_content.contentSize);
			ui.anchorPoint.set(ui_content.anchorPoint);
			ui.node.setPosition(ui_content.node.position);
		});

		this.total_bar.getComponent(UITransform).height = ui_content.height;
		this.total_bar.totalLength = ui_content.height - 15;
		this.total_bar.node.setPosition(0, 0, this.total_bar.node.position.z);
	}

	private createItemCache(item: Node){
		let master_node = item.getChildByName('master');
		let cache: ItemCache = {
			vec_lbl_free: new Vec3(),
			vec_lbl_master: new Vec3(),
			vec_lbl_level: new Vec3(),
			lbl_free: instantiate(this.demo_lbl_free).getComponent(Label),
			lbl_master: instantiate(this.demo_lbl_master).getComponent(Label),
			lbl_level: instantiate(this.demo_lbl_level).getComponent(Label),
			icon_free_check: find('free/icon-get', item),
			icon_master_check: master_node.getChildByName('icon-get'),
			icon_master_lock: master_node.getChildByName('icon-lock'),
			bg_level: item.getChildByName('background-level').getComponent(UITransform),
			master_node,
		};

		[cache.lbl_free, cache.lbl_master, cache.lbl_level].forEach(lbl=>{
			lbl.node.setParent(this.float_view.node);
			lbl.node.active = true;
		});
		[cache.vec_lbl_free, cache.vec_lbl_master, cache.vec_lbl_level].forEach(vec=>vec.set(item.position));

		return cache;
	}

	private refreshLockUI(){
		this.ui_scroll.convertToNodeSpaceAR(this.float_view.convertToWorldSpaceAR(this.lock_vec.bind, this.lock_vec.temp), this.lock_vec.out);

		this.lock_vec.out.y = Math.min(this.lock_vec.out.y, this.va_lock.top-30);

		let height = this.lock_vec.out.y - this.ui_scroll.node.position.y + this.ui_scroll.anchorY * this.ui_scroll.height;
		this.ui_lock.height = height;

		if(height < 0){
			this.lock_vec.out.y = this.ui_scroll.node.position.y - this.ui_scroll.anchorY * this.ui_scroll.height;
			height = 0;
		}

		this.ui_lock.node.setPosition(this.lock_vec.out);
		this.ui_lock.height = height;
	}

	private async activeMaster(btn: Button){
		Popup.ActiveMaster()
		.then(active=>{
			if(active){
				this.refreshUI();
				btn.node.active = false;
				this.node.getChildByName('lbl-active').active = false;
			}else{
				btn.interactable = true;
			}
		});
	}
}

type ItemCache = {
	vec_lbl_free: Vec3;
	vec_lbl_master: Vec3;
	vec_lbl_level: Vec3;
	lbl_free: Label;
	lbl_master: Label;
	lbl_level: Label;
	icon_free_check: Node;
	master_node: Node;
	icon_master_check: Node;
	icon_master_lock: Node;
	bg_level: UITransform;
}
